﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Reflection;

namespace Models
{
    /// <summary>
    /// 模板模竖屏类型
    /// </summary>
    public enum LayoutType
    {
        横屏 = 0,
        竖屏 = 1
    }

    public class Property : DependencyObject
    {
        public string Text { get; set; }

        public bool IsReadOnly { get; set; }

        public Type Type
        {
            get;
            set;
        }

        public object Source { get; set; }

        public PropertyChangedCallback CB;

        public event PropertyChangedCallback Changed;

        public override string ToString()
        {
            return base.ToString();
            //return this.Value.ToString();
        }

        public Property(string text, object value)
        {
            this.Text = text;
            this.Value = value;
            if (value is Enum && !(value is LayoutType))
            {
                this.Type = typeof(Enum);
            }
            else
            {
                this.Type = value.GetType();
            }
        }

        public static bool IsType(Type type, string typeName)
        {
            if (type.ToString() == typeName)
                return true;
            if (type.ToString() == "System.Object")
                return false;

            return IsType(type.BaseType, typeName);
        }

        public static Property QCreate(string text, object value)
        {
            return new Property(text, value);
        }


        public static void MSetValue(object entity, string fieldName, string fieldValue)
        {
            Type entityType = entity.GetType();

            PropertyInfo propertyInfo = entityType.GetProperty(fieldName);

            if (IsType(propertyInfo.PropertyType, "System.String"))
            {
                propertyInfo.SetValue(entity, fieldValue, null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Boolean"))
            {
                propertyInfo.SetValue(entity, Boolean.Parse(fieldValue), null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Int32"))
            {
                if (fieldValue != "")
                    propertyInfo.SetValue(entity, int.Parse(fieldValue), null);
                else
                    propertyInfo.SetValue(entity, 0, null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Double"))
            {
                if (fieldValue != "")
                    propertyInfo.SetValue(entity, double.Parse(fieldValue), null);
                else
                    propertyInfo.SetValue(entity, 0, null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Decimal"))
            {
                if (fieldValue != "")
                    propertyInfo.SetValue(entity, Decimal.Parse(fieldValue), null);
                else
                    propertyInfo.SetValue(entity, new Decimal(0), null);

            }

            if (IsType(propertyInfo.PropertyType, "System.Nullable`1[System.DateTime]"))
            {
                if (fieldValue != "")
                {
                    try
                    {
                        propertyInfo.SetValue(
                            entity, (DateTime?)DateTime.ParseExact(fieldValue, "yyyy-MM-dd HH:mm:ss", null), null);
                    }
                    catch
                    {
                        propertyInfo.SetValue(entity, (DateTime?)DateTime.ParseExact(fieldValue, "yyyy-MM-dd", null), null);
                    }
                }
                else
                    propertyInfo.SetValue(entity, null, null);

            }

        }

        private static void changeCallBack(DependencyObject obj, DependencyPropertyChangedEventArgs e)
        {
            Property p = obj as Property;
            if (p.Source != null)
            {
                MSetValue(p.Source, p.Text, e.NewValue.ToString());
                //p.Source.GetType().GetProperty(p.Text).SetValue(p.Source, e.NewValue, null);

                //p.Source.X = double.Parse(e.NewValue.ToString());
            }
        }

        public Property()
        {
        }

        
        #region Value
        public object Value
        {
            get
            {
                return (GetValue(ValueProgerty));
            }
            set
            {
                SetValue(ValueProgerty, value);
            }
        }
        public static readonly DependencyProperty ValueProgerty =
            DependencyProperty.Register("Value", typeof(object), typeof(Property),
            new PropertyMetadata(null, new PropertyChangedCallback(ChangedCallback)));


        private static void ChangedCallback(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            Property sp = o as Property;
            if (sp.CB != null)
            {
                sp.CB(o, e);
            }

            if (sp.Changed != null)
            {
                sp.Changed(o, e);
            }
        }
        #endregion
    }
}